/*---------------------------------------------------------------------------
	ZaRan	-	A Totallly Automatic CFD Software
	Copyright (C) ,Since 2020
-------------------------------------------------------------------------------
License
	This file is part of ZaRan.

!	@file	gird.h
!	@brief	the purpose of this file.
!	@author	Chen Jie.
\*---------------------------------------------------------------------------*/

#pragma once
#include<vector>
#include"Basic/include/CommonPara.h"
#include"Geometry/include/GeoBase.h"
#include"grid/include/starcd_mesh.h"
#include"CoordTrans/include/CoordTrans.h"
#include"grid/include/grid_node.h"
#include"grid/include/grid_face.h"
#include"grid/include/grid_element.h"
#include"Flux/include/DataField.h"
#include<memory>
using std::vector;
using std::shared_ptr;
//using GridPtr = shared_ptr<Grid>;
//using GridPtrVec = vector<GridPtr>;
//using NodePtr = shared_ptr<GridNode>;
//using NodePtrVec = vector<NodePtr>;

class GridNode;
class GridElement;
class GridFace;
//grid
class Grid
{
public:
	Grid();
	Grid(const Grid& mesh);
public:
	void SetIndex(size_t index) { index_ = index; }
	void SetDim(Dimension dim);
	void SetDim(int dim);
	//	void SetNode(const vector<Point>& node);
	void SetNode(vector<GridNode>& grid_node);
	void SetNodeType(const vector<BoundType>& node_type);
	void SetElement(const vector<GridElement>& element);
	void SetFace(const vector<GridFace>& face);
	void SetNeiborNode(size_t iNode, const vector<size_t>& neibor_node_index, const vector<Grid*>& neibor_node_grid);
	void SetData(size_t iNode, size_t idata, const double& dataValue);
	void SetData(size_t iNode, DataField& dataSet);
	void InitData();
public:
	Dimension GetDim()const;
	GridNode* GetNode(size_t iNode);
	vector<GridNode>* GetNodeVec() { return &node_; }
	Point* GetNodeCoord(size_t iNode);
	BoundType* GetNodeType(int iNode);
	vector<size_t>* GetElementNodeIndex(size_t iElem);
	vector<GridElement>* GetElement() { return &element_; }
	vector<GridFace>* GetFaceVec() { return &face_; }
	vector< GridNode*>* GetNeiborNodePtrVec(size_t iNode);
	vector<CoordTrans>* GetNodeCoordTrans(size_t iNode);
	size_t GetIndex()const { return index_; }
	size_t GetBoundNodeIndex(size_t iNode)const { return boundNodeIndexVec_[iNode]; }
	int GetNodeNum()const;
	int GetNeiborNodeNum(size_t iNode);
	int GetElementNum()const { return element_.size(); }
	int GetBoundNodeNum()const { return boundNodeIndexVec_.size(); }
	double* GetDataValuePtr(size_t iNode, size_t idata);
	DataField* GetDataField(size_t iNode);
public:
	// Set the bound node list from node type list
	void SetBoundNodeIndex();
	// Reorder all nodes' neibor node
	void ReorderNeiborNode();
	// Set the coordinate transition coefficent of all nodes
	void CalCoordTrans();
private:
	// index of itself
	size_t index_;
	//level for overset grid
	int level_;
	// dimension of the mesh
	Dimension dim_;
	// coordinate of all nodes
	vector<GridNode>node_;
	// all elements
	vector<GridElement>element_;
	// all faces
	vector<GridFace>face_;
	// all boundary nodes
	vector<size_t>boundNodeIndexVec_;
	vector<DataField>nodeDataVec_;
};